package com.obas.flex.common.util {

   import com.ease.util.Diagnostics;
   import com.ease.util.ResourceLoader;

   import mx.logging.ILogger;
   import mx.rpc.Fault;

   public class ClientErrorUtil {
      private static const CHANNEL_CALL_FAILED:String = "Channel.Call.Failed";
      private static const CLIENT_CONNECT_FAILED:String = "Client.Error.MessageSend";
      private static const CLIENT_AUTHENTICATION_FAILED:String = "Client.Authorization";

      public static const ERROR_MSG_PROPERTY:String = "errorMsg";
      public static const LOCALIZED_ERROR_MESSAGE:String = "localizedMessage";
      public static const CAUSE:String = "cause";

      public static const CONNECT_ERROR:String = "connectError";
      public static const SERVER_TIME_OUT:String = "timeOutError";
      public static const AUTHENTICATION_ERROR:String = "authenticationError";
      public static const SERVER_ERROR:String = "serverError";
      public static const INTERNAL_ERROR:String = "internalError";
      public static const UNKNOWN_ERROR:String = "unknownError";

      private static const AMF_CONNECT_ERROR:String = "util.amfConnectError";

      public static function getErrorType(error:Error):String {
         var fault:Fault = error as Fault;
         if (fault == null) {
            return UNKNOWN_ERROR;
         }

         if (fault.faultCode == CHANNEL_CALL_FAILED
            || fault.faultCode == CLIENT_CONNECT_FAILED) {
            return CONNECT_ERROR;
         }
         else if (fault.faultCode == CLIENT_AUTHENTICATION_FAILED) {
            return AUTHENTICATION_ERROR;
         }
         else if ((fault.rootCause != null && fault.rootCause.hasOwnProperty(ERROR_MSG_PROPERTY))   // For ServerError, will be removeed.
            || (fault.rootCause != null && fault.rootCause.hasOwnProperty(LOCALIZED_ERROR_MESSAGE)) // For ServerException
         ) {
            if (fault.rootCause[LOCALIZED_ERROR_MESSAGE] == SERVER_TIME_OUT
               || fault.rootCause[LOCALIZED_ERROR_MESSAGE] == AUTHENTICATION_ERROR) {
               return AUTHENTICATION_ERROR;
            }

            return SERVER_ERROR;
         }
         else {
            return INTERNAL_ERROR;
         }
      }

      public static function getErrorString(bundleName:String, resourceKey:String,
                                            error:Error):String {
         var fault:Fault = error as Fault;
         if (fault == null) {
            return "Unknown error: " + error.toString();
         }

         var resourceLoader:ResourceLoader = ResourceLoader.instance();
         var msg:String = fault.faultString;

         const errorType:String = getErrorType(error);
         if (errorType == SERVER_ERROR) {
            msg = getErrorMessage(fault);
         }
         else if (errorType == CONNECT_ERROR) {
            msg = "Cannot connect to the server !";
         }

         return (resourceKey == "") ? msg : resourceLoader.getString(bundleName, resourceKey, [msg]);
      }

      private static function getErrorMessage(fault:Fault):String {
         if (fault.rootCause != null && fault.rootCause.hasOwnProperty(ERROR_MSG_PROPERTY)) {
            return fault.rootCause[ERROR_MSG_PROPERTY];
         }
         else if (fault.rootCause != null && fault.rootCause.hasOwnProperty(LOCALIZED_ERROR_MESSAGE)) {
            return fault.rootCause[LOCALIZED_ERROR_MESSAGE];
         }

         return null;
      }

      private static function getErrorStack(fault:Fault):String {
         if (fault.rootCause != null && fault.rootCause.hasOwnProperty(LOCALIZED_ERROR_MESSAGE)) {
            var message:String = fault.rootCause[LOCALIZED_ERROR_MESSAGE];
            var cause:Object = fault.rootCause[CAUSE];
            while (cause != null) {
               message += "\n";
               if (cause.hasOwnProperty(LOCALIZED_ERROR_MESSAGE)) {
                  message += cause[LOCALIZED_ERROR_MESSAGE];
               }
               cause = cause[CAUSE];
            }
            return message;
         }

         return fault.toString();
      }
   }
}